package com.yanjiali.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.yanjiali.enumerate.LoginTypeEnum;
import com.yanjiali.feign.JwtToken;
import com.yanjiali.feign.OAuth2FeignClient;
import com.yanjiali.model.R;
import com.yanjiali.model.req.LogOutReq;
import com.yanjiali.model.resp.LogOutResp;
import com.yanjiali.model.resp.LoginResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yanjiali.entity.SysUser;
import com.yanjiali.mapper.SysUserMapper;
import com.yanjiali.service.SysUserService;
/**
 * @Package: com.yanjiali.service.impl
 * @Author: yanjiali
 * @Created: 2025/4/10 22:35
*/
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService{

    @Autowired
    private OAuth2FeignClient oAuth2FeignClient;

    //TODO 对应：tenseek-api:tenseek-secret 的Base64编码
    @Value("${basic.token:Basic dGVuc2Vlay1hcGk6dGVuc2Vlay1zZWNyZXQ=}")
    private String basicType;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public R<LoginResp> login(String username, String password) {
        log.info("管理员开始登录: {}", username);

        //1、获取token 需要远程调用authorization-server 该服务
        ResponseEntity<JwtToken> tokenResponseEntity
                = oAuth2FeignClient.getToken("password", username, password, LoginTypeEnum.ADMIN_TYPE.getLoginType(), basicType);
        if(tokenResponseEntity.getStatusCode() != HttpStatus.OK) {
            throw new ApiException(ApiErrorCode.FAILED);
        }
        JwtToken jwtToken = tokenResponseEntity.getBody();
        log.info("远程调用授权服务器成功，获取的token为{}", JSON.toJSONString(jwtToken, true));
        String token = jwtToken.getAccessToken();   //获取请求体中的token
        String refreshToken = jwtToken.getRefreshToken();   //获取请求体中的refreshToken

        //2、权限数据怎么查询 -- 不需要查询 jwt中已经包含
        Jwt jwt = JwtHelper.decode(token);      // 解码给定的 JWT Token
        String jwtJsonStr = jwt.getClaims();    // 获取解码后的 JWT Token 的声明部分（Claims），返回一个字符串
        JSONObject jwtJson = JSON.parseObject(jwtJsonStr);  //获取json格式的jwt串
        JSONArray authoritiesJsonArray = jwtJson.getJSONArray("authorities");
        List<SimpleGrantedAuthority> authorities = authoritiesJsonArray.stream()
                .map(authoritiesJson -> new SimpleGrantedAuthority(authoritiesJson.toString()))
                .collect(Collectors.toList());

        //TODO 将该token存储到redis里面，配置我们的网关jwt验证操作，并设置对应的过期时间
        stringRedisTemplate.opsForValue().set(token, "", jwtToken.getExpiresIn(), TimeUnit.SECONDS);

        return R.ok(new LoginResp(token, refreshToken, authorities));
    }

    @Override
    public R<LogOutResp> logOut(LogOutReq logOutReq) {
        stringRedisTemplate.delete(logOutReq.getToken());
        return R.ok(new LogOutResp());
    }
}
